package com.deyuanyun.pic.pipe.support.utils;

import java.math.BigDecimal;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.deyuanyun.pic.common.util.MapUtil;


/**
 * 场站阀室中心点计算
 * 
 * @author scalpel
 * @version 1.0
 * @date 2016年3月29日上午11:11:54
 * Method List:                       // 主要函数及其功能
 *             1.---------------- 
 *History:                           // 历史修改记录
 */
public class ValveRoomCenterPoint {
	
	public static Double getVal(Object v){
		if(v instanceof BigDecimal)
		{
			return ((BigDecimal)v).doubleValue();
		}
		return 0d;
	};
	
	public static Map<String,Object> getCenterPoint(List<Map<String,Object>> data) throws Exception {
		Point centerPoint = new Point();
		// 通过获取xy坐标的最大最小值来构建要素集的矩形框
		if (data.size() > 0) {
			Map<String,Object> d=data.get(0);
			double maxX = 0, maxY = 0, minX = 0, minY = 0;
				maxX = getVal(d.get("CONVERT_X"));
				maxY = getVal(d.get("CONVERT_Y"));
				minX = getVal(d.get("CONVERT_X"));
				minY = getVal(d.get("CONVERT_Y"));
			for (int i = 0; i < data.size(); i++) {
				d=data.get(0);
				if (getVal(d.get("CONVERT_X")) > maxX) {
					maxX = getVal(d.get("CONVERT_X"));
				}
				if (getVal(d.get("CONVERT_Y")) > maxY) {
					maxY = getVal(d.get("CONVERT_Y"));
				}
				if (getVal(d.get("CONVERT_X")) < minX) {
					minX = getVal(d.get("CONVERT_X"));
				}
				if (getVal(d.get("CONVERT_Y")) < minY) {
					minY = getVal(d.get("CONVERT_Y"));
				}
			}
			double centerPointLng = (maxX + minX) / 2;
			double centerPointLat = (maxY + minY) / 2;
			centerPoint.x= centerPointLng;
			centerPoint.y= centerPointLat;
			// 判断是否在多边形内
			if (isInPolygon(centerPoint, data)) {
				// 凸多边形
				return ToMap(centerPoint);
			} else {
				// 凹多变形返回边上一点。
				return ToMap(new Point(data.get(0)));
			}
		} else {
			return ToMap(centerPoint);
		}
	}
	
	private static Map<String,Object> ToMap(Point p)
	{
		Map<String,Object> result=new HashMap<String,Object>(); 
		result.put("x", p.x);
		result.put("y", p.y);
		return result;
	}
	
	
	/**
	 * 
	  * 判断是否是中心点
	  *
	  * @param 
	  * @return 
	  * @throws  
	  * @see    
	  * Table Accessed: 
	  * Table Updated: 
	  * Other:       
	  *
	 */
	private static boolean isInPolygon(Point point, List<Map<String,Object>> data) {
		
		int nCross = 0;
		for (int i = 0; i < data.size(); i++) {
			Point p1 = new Point(data.get(i));
			Point p2 = new Point(data.get((i + 1) % data.size()));
			// 求解 y=p.y 与 p1 p2 的交点
			// p1p2 与 y=p0.y平行
			if (p1.y == p2.y)
				continue;
			// 交点在p1p2延长线上
			if (point.y < Math.min(p1.y, p2.y))
				continue;
			// 交点在p1p2延长线上
			if (point.y >= Math.max(p1.y, p2.y))
				continue;
			// 求交点的 X 坐标
			double x = (double) (point.y - p1.y) * (double) (p2.x - p1.x)
					/ (double) (p2.y - p1.y) + p1.x;
			// 只统计单边交点
			if (x > point.x)
				nCross++;
		}
		return (nCross % 2 == 1);
	}
	
	static class Point
	{
		private double x;
		private double y;
		public Point()
		{
			
		}
		
		
		
		
		public double getX() {
			return x;
		}




		public void setX(double x) {
			this.x = x;
		}




		public double getY() {
			return y;
		}




		public void setY(double y) {
			this.y = y;
		}




		public Point(Map<String,Object> p)
		{
			x=getVal(p.get("CONVERT_X"));
			y=getVal(p.get("CONVERT_Y"));	
		}
	}
}
